package cn.sibu.tuchapplication;

import android.content.Context;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.widget.ImageView;

/**
 * Created by 刘红亮 on 15-12-23 上午10:01.
 */
public class RotateZoomImageView extends ImageView {

    private ScaleGestureDetector mScaleDetector;
    private Matrix mImageMatrix;
    /*上次的旋转角度*/
    private int mLastAngle = 0;
    /*变换时的轴点*/
    private int mPivotX,mPivotY;

    public RotateZoomImageView(Context context) {
        super(context);
        init(context);
    }

    public RotateZoomImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public RotateZoomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context){
        mScaleDetector = new ScaleGestureDetector(context,mScaleListener);
        setScaleType(ScaleType.MATRIX);
        mImageMatrix = new Matrix();
    }
    /**
     * 在onSizeChanged()中根据视图的尺寸计算一些值
     * 这个视图在init()期间并没有尺寸,因此必须等到这个回调方法才能得到尺寸
     * */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        Log.e("onSizeChanged","onSizeChanged");
        if(w!=oldw||h!=oldh){
            //将图片移到视图中央
            int translateX = Math.abs(w-getDrawable().getIntrinsicWidth())/2;
            int translateY = Math.abs(h-getDrawable().getIntrinsicHeight())/2;
            setImageMatrix(mImageMatrix);
            //得到未缩放和旋转变换时的中轴点
            mPivotX = w/2;
            mPivotY = h/2;
        }
    }



    private ScaleGestureDetector.SimpleOnScaleGestureListener mScaleListener = new ScaleGestureDetector.SimpleOnScaleGestureListener(){
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            //ScaleGestureDetector会根据手指的分开和合拢计算出缩放因子
            float scaleFactor = detector.getScaleFactor();

            //将缩放因子传给图片进行缩放
            mImageMatrix.postScale(scaleFactor,scaleFactor,mPivotX,mPivotY);
            setImageMatrix(mImageMatrix);
            return true;
        }
    };

    /**
     * 处理两根手指的事件来旋转图片
     * 这个方法根据触点间的角度变化对图片进行相应的旋转
     * 当用户旋转手指时,图片也会跟着旋转
     * */

    private boolean doRotationEvent(MotionEvent event){
        //计算两根手指间的角度
        float deltaX = event.getX(0) - event.getX(1);
        float deltaY = event.getY(0) - event.getY(1);
        double radians = Math.atan(deltaY/deltaX);
        //转换角度
        int degrees = (int) (radians*180/Math.PI);
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //记住初始位置
                mLastAngle = degrees;
                break;
            case MotionEvent.ACTION_MOVE:
                //返回一个转换后的介于-90度和+90度的值
                //这样在两根手指垂直触摸时可以得到翻转信号和相应的角度
                //这种情况下会将图片在我们侦测到的方向上旋转一个很小的角度(5度)
                if((degrees-mLastAngle)>45){
                    //逆时针旋转(可以超出边界)
                    mImageMatrix.postRotate(-5,mPivotX,mPivotY);
                }else if((degrees-mLastAngle)<-45){
                    //顺时针旋转(可以超出边界)
                    mImageMatrix.postRotate(5,mPivotX,mPivotY);
                }else {
                    //正常旋转,旋转角度即为手指的旋转角度
                    mImageMatrix.postRotate(degrees - mLastAngle,mPivotX,mPivotY);
                }
                //将旋转矩阵发送给图片
                setImageMatrix(mImageMatrix);
                //保存当前的角度
                break;
        }
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN){
            //我们并不直接关心这个事件,但会声明要处理后续的多点触摸
            return true;
        }

        switch (event.getPointerCount()){
            case 3:
                //按下三根手指时,使用ScaleGestureDetector缩放图片
                return mScaleDetector.onTouchEvent(event);
            case 2:
                //按下两根手指时,根据手指操作旋转图片
                return doRotationEvent(event);
            default:
                //忽略这个事件

                return super.onTouchEvent(event);
        }
    }
}
